package com.slofzx.nuoda.evaluation.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.slofzx.nuoda.common.feign.OfficeClient;
import com.slofzx.nuoda.common.util.IdGen;
import com.slofzx.nuoda.evaluation.param.dao.CommonBaseIrrDAO;
import com.slofzx.nuoda.evaluation.param.dao.CommonFixedDAO;
import com.slofzx.nuoda.evaluation.param.dao.CommonUnitCostDAO;
import com.slofzx.nuoda.evaluation.param.dto.CommonBaseIrrDTO;
import com.slofzx.nuoda.evaluation.param.dto.CommonFixedDTO;
import com.slofzx.nuoda.evaluation.param.dto.CommonUnitCostDTO;
import com.slofzx.nuoda.evaluation.param.dto.ProjectCostDataDTO;
import com.slofzx.nuoda.evaluation.param.entity.CommonBaseIrr;
import com.slofzx.nuoda.evaluation.param.entity.CommonFixed;
import com.slofzx.nuoda.evaluation.param.entity.CommonUnitCost;
import com.slofzx.nuoda.evaluation.param.service.ProjectCostDataService;
import com.slofzx.nuoda.evaluation.project.dao.BatchInfoDAO;
import com.slofzx.nuoda.evaluation.project.dao.PlanInfoDAO;
import com.slofzx.nuoda.evaluation.project.dao.ProjectYearDataDAO;
import com.slofzx.nuoda.evaluation.project.dto.*;
import com.slofzx.nuoda.evaluation.project.entity.BatchInfo;
import com.slofzx.nuoda.evaluation.project.entity.PlanInfo;
import com.slofzx.nuoda.evaluation.project.entity.ProjectInfo;
import com.slofzx.nuoda.evaluation.project.entity.ProjectYearData;
import com.slofzx.nuoda.evaluation.project.enums.*;
import com.slofzx.nuoda.evaluation.project.observer.BatchObserver;
import com.slofzx.nuoda.evaluation.project.observer.ProjectObserver;
import com.slofzx.nuoda.evaluation.project.util.CglibUtils;
import com.slofzx.nuoda.evaluation.project.util.DoubleUtil;
import com.slofzx.nuoda.evaluation.project.vo.ProjectInfoVO;
import com.slofzx.nuoda.evaluation.project.dao.ProjectInfoDAO;
import com.slofzx.nuoda.evaluation.project.service.ProjectInfoService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.slofzx.nuoda.common.enums.CommonResultEnum;
import com.slofzx.nuoda.common.enums.ServiceResult;
import com.slofzx.nuoda.common.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;

import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 项目信息服务实现类
 *
 * @author nuoda
 * @since 2023-10-20 11:04:00
 */
@Service("projectInfoService")
public class ProjectInfoServiceImpl extends BaseServiceImpl implements ProjectInfoService, BatchObserver {

    @Resource
    private ProjectInfoDAO projectInfoDAO;
    @Resource
    private ProjectYearDataDAO projectYearDataDAO;
    @Resource
    private BatchInfoDAO batchInfoDAO;
    @Autowired
    private OfficeClient officeClient;
    @Autowired(required = false)
    protected Set<ProjectObserver> projectObserverSet;
    @Autowired
    private PlanInfoDAO planInfoDAO;
    @Resource
    private CommonBaseIrrDAO commonBaseIrrDAO;
    @Resource
    private CommonFixedDAO commonFixedDAO;
    @Resource
    private CommonUnitCostDAO commonUnitCostDAO;
    @Resource
    private ProjectCostDataService projectCostDataService;



    /**
     * 将数据表数据转换为返回数据类型
     *
     * @param entity 数据表对应类
     * @return 实例对象
     */
    protected ProjectInfoVO parseEntity2VO(ProjectInfo entity) {
        ProjectInfoVO vo = new ProjectInfoVO();
        vo.setId(entity.getId());
        vo.setName(entity.getName());
        vo.setType(entity.getType());
        vo.setBuildOffice(entity.getBuildOffice());
        vo.setEvaluationPeriod(entity.getEvaluationPeriod());
        vo.setBuildYearCount(entity.getBuildYearCount());
        vo.setProductType(entity.getProductType());
        vo.setProductProperty(entity.getProductProperty());
        vo.setPoolType(entity.getPoolType());
        vo.setAreaMark(entity.getAreaMark());
        vo.setEvaluationMethod(entity.getEvaluationMethod());
        vo.setYear(entity.getYear());
        vo.setBatchId(entity.getBatchId());
       // vo.setNetAssetsUnUse(entity.getNetAssetsUnUse());
        vo.setResourceRate(entity.getResourceRate());
        vo.setCreateUser(entity.getCreateUser());
        vo.setCreateTime(entity.getCreateTime());
        vo.setRegion(entity.getRegion());
        vo.setOilGasField(entity.getOilGasField());
        vo.setCapacityType(entity.getCapacityType());
        vo.setDisplacementMethod(entity.getDisplacementMethod());
        vo.setDrillOilWellCount(entity.getDrillOilWellCount());
        vo.setDrillWaterWellCount(entity.getDrillWaterWellCount());
        vo.setDrillWellCount(entity.getDrillWellCount());
        vo.setStraightWellDeth(entity.getStraightWellDeth());
        vo.setHorizontalWellDeth(entity.getHorizontalWellDeth());
        vo.setIntoRuler(entity.getIntoRuler());
        vo.setInfOilWellCount(entity.getInfOilWellCount());
        vo.setInfWaterWellCount(entity.getInfWaterWellCount());
        vo.setInfWellCount(entity.getInfWellCount());
        vo.setBuiltUpCapacity(entity.getBuiltUpCapacity());
        vo.setStraightWellOutput(entity.getStraightWellOutput());
        vo.setHorizontalWellOutput(entity.getHorizontalWellOutput());
        vo.setHorizontalWellCount(entity.getHorizontalWellCount());
        vo.setBuildHorizontalWellCount(entity.getBuildHorizontalWellCount());
        vo.setRegionOilGasRate(entity.getRegionOilGasRate());
        vo.setOldNetWorth(entity.getOldNetWorth());
        vo.setBaseIrr(entity.getBaseIrr());
        vo.setComputeId(entity.getComputeId());
        vo.setUltimate(entity.isUltimate());
        vo.setOther1(entity.getOther1());
        vo.setOther2(entity.getOther2());
        vo.setWellOutput(entity.getWellOutput());
        vo.setProductionDay(entity.getProductionDay());
        return vo;
    }

    /**
     * 将数据传递类转换为数据表数据类
     *
     * @param dto 数据传递类实例
     * @return 实例对象
     */
    protected ProjectInfo parseDTO2Entity(ProjectInfoSaveDTO dto) {
        ProjectInfo entity = new ProjectInfo();
        entity.setId(dto.getId());
        entity.setName(dto.getName());
        entity.setOther1(dto.getOther1());
        entity.setOther2(dto.getOther2());
        entity.setProductionDay(dto.getProductionDay());
        entity.setWellOutput(dto.getWellOutput());
        entity.setType(dto.getType());
        entity.setBuildOffice(dto.getBuildOffice());
        entity.setResourceRate(dto.getResourceRate());
        entity.setEvaluationPeriod(dto.getEvaluationPeriod());
        entity.setBuildYearCount(dto.getBuildYearCount());
        entity.setProductType(dto.getProductType());
        entity.setProductProperty(dto.getProductProperty());
        entity.setPoolType(dto.getPoolType());
        entity.setAreaMark(dto.getAreaMark());
        entity.setEvaluationMethod(dto.getEvaluationMethod());
        entity.setYear(dto.getYear());
        entity.setBatchId(dto.getBatchId());
        entity.setRegion(dto.getRegion());
        entity.setOilGasField(dto.getOilGasField());
        entity.setCapacityType(dto.getCapacityType());
        entity.setDisplacementMethod(dto.getDisplacementMethod());
        entity.setDrillOilWellCount(dto.getDrillOilWellCount());
        entity.setDrillWaterWellCount(dto.getDrillWaterWellCount());
        entity.setDrillWellCount(dto.getDrillWellCount());
        entity.setStraightWellDeth(dto.getStraightWellDeth());
        entity.setHorizontalWellDeth(dto.getHorizontalWellDeth());
        entity.setIntoRuler(dto.getIntoRuler());
        entity.setInfOilWellCount(dto.getInfOilWellCount());
        entity.setInfWaterWellCount(dto.getInfWaterWellCount());
        entity.setInfWellCount(dto.getInfWellCount());
        entity.setBuiltUpCapacity(dto.getBuiltUpCapacity());
        entity.setStraightWellOutput(dto.getStraightWellOutput());
        entity.setHorizontalWellOutput(dto.getHorizontalWellOutput());
        entity.setHorizontalWellCount(dto.getHorizontalWellCount());
        entity.setBuildHorizontalWellCount(dto.getBuildHorizontalWellCount());
        entity.setRegionOilGasRate(dto.getRegionOilGasRate());
        entity.setOldNetWorth(dto.getOldNetWorth());
        entity.setBaseIrr(dto.getBaseIrr());
        entity.setUltimate(dto.isUltimate());
        return entity;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ProjectInfoVO queryById(String id) {
        ProjectInfo entity = this.projectInfoDAO.selectById(id);
        if (entity == null) {
            return null;
        }
        return parseEntity2VO(entity);
    }

    @Override
    public List<ProjectInfoVO> queryList(ProjectInfoDTO dto) {
        final List<ProjectInfo> dataList = projectInfoDAO.queryList(dto);
        List<ProjectInfoVO> list = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(dataList)) {
            for (ProjectInfo projectInfo : dataList) {
                final ProjectInfoVO vo = parseEntity2VO(projectInfo);
                list.add(vo);
            }
        }
        return list;
    }

//    @Override
//    public List<ProjectInfoVO> queryListHasVersion(ProjectInfoDTO dto) {
//        final List<ProjectInfo> dataList = projectInfoDAO.queryListHasVersion(dto);
//        List<ProjectInfoVO> list = new ArrayList<>();
//        if(CollectionUtils.isNotEmpty(dataList)) {
//            for (ProjectInfo projectInfo : dataList) {
//                final ProjectInfoVO vo = parseEntity2VO(projectInfo);
//                list.add(vo);
//            }
//        }
//        return list;
//    }

    /**
     * 查询多条数据
     *
     * @param dto 数据传递类实例对象
     * @return 对象列表
     */
    @Override
    public List<ProjectInfoVO> queryVOList(ProjectInfoDTO dto) {

        List<ProjectInfoVO> dataList = this.projectInfoDAO.queryVOList(dto);
        if (CollectionUtils.isEmpty(dataList)) {
            return dataList;
        }
        for (ProjectInfoVO vo : dataList) {
            vo.setTotalInvest(DoubleUtil.getScale(vo.getTotalInvest(), 2));
            vo.setBalanceConstructionInvest(DoubleUtil.getScale(vo.getBalanceConstructionInvest(), 2));
            vo.setBalanceSumOilOutput(DoubleUtil.getScale(vo.getBalanceSumOilOutput(), 2));
            vo.setBalanceSumGasOutput(DoubleUtil.getScale(vo.getBalanceSumGasOutput(), 2));
        }
        if (dto.isBatchName()) {
            Set<String> batchIds = new HashSet<>(dataList.size());
            Set<String> planIdSet = new HashSet<>();
            for (ProjectInfoVO vo : dataList) {
                final String batchQuality = vo.getBatchQuality();
                if (BatchQualityEnum.PLAN.getId().equals(batchQuality)) {
                    planIdSet.add(vo.getBatchId());
                } else {
                    batchIds.add(vo.getBatchId());
                }

            }
            Map<String, String> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(batchIds)) {
                final BatchInfoDTO batchInfoDTO = new BatchInfoDTO();
                batchInfoDTO.setFilterIdSet(batchIds);
                final List<BatchInfo> batchInfos = batchInfoDAO.queryList(batchInfoDTO);
                map = batchInfos.stream().collect(Collectors.toMap(BatchInfo::getId, BatchInfo::getName));
            }
            Map<String, String> planNameMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(planIdSet)) {
                final PlanInfoDTO planInfoDTO = new PlanInfoDTO();
                planInfoDTO.setFilterIdSet(planIdSet);
                final List<PlanInfo> planInfos = planInfoDAO.queryList(planInfoDTO);
                planNameMap = planInfos.stream().collect(Collectors.toMap(PlanInfo::getId, PlanInfo::getName));
            }
            for (ProjectInfoVO vo : dataList) {
                final String batchId = vo.getBatchId();
                vo.setBatchName(map.getOrDefault(batchId, planNameMap.get(batchId)));
            }
        }
        return dataList;
    }

    /**
     * 新增数据
     *
     * @param dto 实例对象
     * @return 操作结果
     */
    @Transactional
    @Override
    public ServiceResult create(ProjectInfoSaveDTO dto) {
        // TODO 添加校验逻辑
        ProjectInfo entity = parseDTO2Entity(dto);
        preInsert(entity);
        this.projectInfoDAO.insert(entity);
        if(projectObserverSet!=null) {
            for(ProjectObserver item:projectObserverSet) {
                ServiceResult result = item.handleProjectCreate(entity.getId());
                if(CommonResultEnum.SUCCESS != result) {
                    logger.error("项目监听者 {} 处理项目创建事件失败: {}",item.getName(),result);
                }
            }
        }
        return CommonResultEnum.SUCCESS;
    }

    /**
     * 修改数据
     *
     * @param dto 实例对象
     * @return 操作结果
     */
    @Override
    public ServiceResult update(ProjectInfoSaveDTO dto) {
        String id = dto.getId();
        if (StringUtils.isEmpty(id)) {
            return CommonResultEnum.NOT_EXIST;
        }
        ProjectInfo entity = this.projectInfoDAO.selectById(id);
        if (entity == null) {
            return CommonResultEnum.NOT_EXIST;
        }
        // TODO 添加其他校验逻辑，如数据权限

        entity.setName(dto.getName());
        entity.setOther1(dto.getOther1());
        entity.setOther2(dto.getOther2());
        entity.setWellOutput(dto.getWellOutput());
        entity.setProductionDay(dto.getProductionDay());
        entity.setType(dto.getType());
        entity.setBuildOffice(dto.getBuildOffice());
        entity.setEvaluationPeriod(dto.getEvaluationPeriod());
        entity.setBuildYearCount(dto.getBuildYearCount());
        entity.setProductProperty(dto.getProductProperty());
        entity.setPoolType(dto.getPoolType());
        entity.setResourceRate(dto.getResourceRate());
        entity.setAreaMark(dto.getAreaMark());
        entity.setEvaluationMethod(dto.getEvaluationMethod());
        entity.setYear(dto.getYear());
        entity.setBatchId(dto.getBatchId());
        entity.setRegion(dto.getRegion());
        entity.setOilGasField(dto.getOilGasField());
        entity.setCapacityType(dto.getCapacityType());
        entity.setDisplacementMethod(dto.getDisplacementMethod());
        entity.setDrillOilWellCount(dto.getDrillOilWellCount());
        entity.setDrillWaterWellCount(dto.getDrillWaterWellCount());
        entity.setDrillWellCount(dto.getDrillWellCount());
        entity.setStraightWellDeth(dto.getStraightWellDeth());
        entity.setHorizontalWellDeth(dto.getHorizontalWellDeth());
        entity.setIntoRuler(dto.getIntoRuler());
        entity.setInfOilWellCount(dto.getInfOilWellCount());
        entity.setInfWaterWellCount(dto.getInfWaterWellCount());
        entity.setInfWellCount(dto.getInfWellCount());
        entity.setBuiltUpCapacity(dto.getBuiltUpCapacity());
        entity.setStraightWellOutput(dto.getStraightWellOutput());
        entity.setHorizontalWellOutput(dto.getHorizontalWellOutput());
        entity.setHorizontalWellCount(dto.getHorizontalWellCount());
        entity.setBuildHorizontalWellCount(dto.getBuildHorizontalWellCount());
        entity.setRegionOilGasRate(dto.getRegionOilGasRate());
        entity.setOldNetWorth(dto.getOldNetWorth());
        entity.setBaseIrr(dto.getBaseIrr());
        entity.setUltimate(dto.isUltimate());
        // 撤销其他项目最终版本
        if(dto.isUltimate()) {
            cancelUltimate(dto.getBatchId());
        }

        this.projectInfoDAO.updateById(entity);
        return CommonResultEnum.SUCCESS;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 操作结果
     */
    @Override
    @Transactional
    public ServiceResult deleteById(String id) {
        if(StringUtils.isBlank(id)){
            return CommonResultEnum.VALUE_LOOSE;
        }
        this.projectInfoDAO.deleteById(id);

        LambdaQueryWrapper<ProjectYearData> deleteWrapper = new LambdaQueryWrapper();
        deleteWrapper.eq(ProjectYearData::getProjectId,id);
        projectYearDataDAO.delete(deleteWrapper);
        if(projectObserverSet!=null) {
            for(ProjectObserver item:projectObserverSet) {
                ServiceResult result = item.handleProjectDelete(id);
                if(CommonResultEnum.SUCCESS != result) {
                    logger.error("项目监听者 {} 处理项目删除事件失败: {}",item.getName(),result);
                }
            }
        }
        return CommonResultEnum.SUCCESS;
    }

    @Override
    @Transactional
    public ServiceResult deleteByBatch(String batchId) {
        LambdaQueryWrapper<ProjectInfo> projectWrapper = new LambdaQueryWrapper();
        projectWrapper.eq(ProjectInfo::getBatchId,batchId);
        List<ProjectInfo> projectInfoList = projectInfoDAO.selectList(projectWrapper);

        if(projectInfoList != null && !projectInfoList.isEmpty()){
            List<String> projectIdList = projectInfoList.stream().map(ProjectInfo::getId).collect(Collectors.toList());
            LambdaQueryWrapper<ProjectYearData> deleteProjYearWrapper = new LambdaQueryWrapper();
            deleteProjYearWrapper.in(ProjectYearData::getProjectId,projectIdList);
            projectYearDataDAO.delete(deleteProjYearWrapper);
            projectCostDataService.deleteByBatchId(projectIdList);
        }
        projectInfoDAO.delete(projectWrapper);
        return CommonResultEnum.SUCCESS;
    }

    @Override
    @Transactional
    public Map<String,String> importExcelData(String batchId,BatchQualityEnum quality, List<ProjectInfoSaveDTO> excelOriDataList) {
        if (StringUtils.isBlank(batchId)) {
            return null;
        }
        Map<String, String> resultMap = new HashMap<>();
        if (excelOriDataList == null || excelOriDataList.isEmpty()) {
            return resultMap;
        }
        //DONE：Excel数据去重
        PlanInfo planInfo = null;
        List<ProjectInfoSaveDTO> noDuplicateDataList = new ArrayList<>();
        String paramVersion = null;
        // 方案类任务不进行根据项目名称去重
        if (BatchQualityEnum.PLAN == quality) {
            planInfo = planInfoDAO.selectById(batchId);
            noDuplicateDataList = excelOriDataList;
            paramVersion = planInfo.getParamVersion();
        } else {
            paramVersion = batchInfoDAO.selectById(batchId).getParamVersion();
            List<String> projectNames = new ArrayList<>();
            for (ProjectInfoSaveDTO infoDTO : excelOriDataList) {
                String name = infoDTO.getName();
                if (projectNames.isEmpty()) {
                    projectNames.add(name);
                } else {
                    if (projectNames.contains(name)) {
                        int index = projectNames.indexOf(name);
                        noDuplicateDataList.remove(index);
                    }
                }
                noDuplicateDataList.add(infoDTO);
            }
            //DONE：格式化参数
            // List<ProjectInfoExcelDTO> excelDataList = this.filterUnqualifiedData(noDuplicateExcelDataList);
            if (noDuplicateDataList == null) {
                return resultMap;
            }
        }
        CommonBaseIrrDTO commonBaseIrrDTO = new CommonBaseIrrDTO();
        commonBaseIrrDTO.setVersionId(paramVersion);
        List<CommonBaseIrr> commonBaseIrrList = commonBaseIrrDAO.queryList(commonBaseIrrDTO);
        final CommonFixedDTO commonFixedDTO = new CommonFixedDTO();
        commonFixedDTO.setVersionId(paramVersion);
        final List<CommonFixed> commonFixeds = commonFixedDAO.queryList(commonFixedDTO);
        final CommonUnitCostDTO commonUnitCostDTO = new CommonUnitCostDTO();
        commonUnitCostDTO.setVersionId(paramVersion);
        final List<CommonUnitCost> commonUnitCosts = commonUnitCostDAO.queryList(commonUnitCostDTO);
        Map<String, Double> irrMap = commonBaseIrrList.stream().collect(Collectors.toMap(CommonBaseIrr::getPoolType, CommonBaseIrr::getValue, (key1, key2) -> key2));
        final Map<String, CommonUnitCost> commonUnitCostMap = commonUnitCosts.stream().collect(Collectors.toMap(CommonUnitCost::getCompanyId, Function.identity(), (v1, v2) -> v1));
        //DONE：删除已导入数据
        LambdaQueryWrapper<ProjectInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProjectInfo::getBatchId, batchId);
        projectInfoDAO.delete(queryWrapper);
        //DONE：已存在数据转换并存储
        final String userId = getUserId();
        List<ProjectCostDataDTO> projectCostDataList = new ArrayList<>(noDuplicateDataList.size());
        List<ProjectInfo> entityList = new ArrayList<>(noDuplicateDataList.size());
        Integer sort = 0;
        for (ProjectInfoSaveDTO dto : noDuplicateDataList) {
            final ProjectInfo projectInfo = parseDTO2Entity(dto);
            projectInfo.setCreateUser(userId);
            projectInfo.setCreateTime(new Date());
            projectInfo.setId(IdGen.uuid());
            projectInfo.setBatchId(batchId);
            projectInfo.setSort(sort);
            if (dto.getProductionDay() == null || dto.getProductionDay() == 0D) {
                projectInfo.setProductionDay(300);
            }
            // 资源税默认6%
            if (dto.getResourceRate() == null || dto.getResourceRate() == 0D) {
                projectInfo.setResourceRate(6D);
            }
            if (projectInfo.getBaseIrr() == null || projectInfo.getBaseIrr() == 0) {
                if (BatchQualityEnum.PLAN == quality) {
                    projectInfo.setBaseIrr(irrMap.get(planInfo.getPoolType()));
                } else {
                    projectInfo.setBaseIrr(irrMap.get(projectInfo.getPoolType()));
                }
            }
            projectInfo.setBatchQuality(quality.getId());
            entityList.add(projectInfo);

            String buildOffice = projectInfo.getBuildOffice();
            // 方案类任务的项目根据评价方法区分项目
            if (BatchQualityEnum.PLAN == quality) {
                if (planInfo != null) {
                    projectInfo.setBuildOffice(planInfo.getBuildOffice());
                    projectInfo.setAreaMark(planInfo.getAreaMark());
                    projectInfo.setRegion(planInfo.getRegion());
                    projectInfo.setPoolType(planInfo.getPoolType());
                    projectInfo.setProductProperty(planInfo.getProductProperty());
                    projectInfo.setYear(planInfo.getYear());
                    projectInfo.setCapacityType(planInfo.getCapacityType());
                    projectInfo.setDisplacementMethod(planInfo.getDisplacementMethod());
                    buildOffice = planInfo.getBuildOffice();
                }
                resultMap.put(projectInfo.getEvaluationMethod(), projectInfo.getId());
            } else {
                resultMap.put(projectInfo.getName(), projectInfo.getId());
            }
            // 设置成本参数数据
            final ProjectCostDataDTO projectCostData = new ProjectCostDataDTO();
            if (CollectionUtils.isNotEmpty(commonFixeds)) {
                final CommonFixed commonFixed = commonFixeds.get(0);
                CglibUtils.copy(commonFixed, projectCostData);
            }

            if (MapUtils.isNotEmpty(commonUnitCostMap)) {
                final CommonUnitCost commonUnitCost = commonUnitCostMap.get(buildOffice);
                CglibUtils.copy(commonUnitCost, projectCostData);
            }
            projectCostData.setId(projectInfo.getId());
            projectCostDataList.add(projectCostData);
            sort++;
        }
       projectCostDataService.batchSave(projectCostDataList);
        int i = this.saveBatch(entityList, projectInfoDAO, 200);
        return resultMap;
    }

    @Override
    @Transactional
    public ServiceResult editProjectYearData(ProjectInfoSaveDTO dto) {
        String id = dto.getId();
        if(StringUtils.isBlank(id)){
            return CommonResultEnum.VALUE_LOOSE;
        }
        ProjectInfo projectInfo = projectInfoDAO.selectById(id);
        if(projectInfo == null){
            return CommonResultEnum.NOT_EXIST;
        }
        ProjectInfo updateEntity = this.parseDTO2Entity(dto);
        projectInfoDAO.updateById(updateEntity);

        List<ProjectYearDataDTO> yearDataDTOList = dto.getYearDataDTOList();
        if(yearDataDTOList != null && !yearDataDTOList.isEmpty()){
            String batchId = updateEntity.getBatchId();
            // 查询项目年份参数保留之前的年份参数
            final ProjectYearDataDTO projectYearDataDTO = new ProjectYearDataDTO();
            projectYearDataDTO.setProjectId(projectInfo.getId());
            final List<ProjectYearData> projectYearDataList = projectYearDataDAO.queryList(projectYearDataDTO);
            Map<Integer, ProjectYearData> yearDataMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(projectYearDataList)) {
                yearDataMap = projectYearDataList.stream().filter(Objects::nonNull)
                        .collect(Collectors.toMap(ProjectYearData::getYear, Function.identity(), (v1, v2) -> v1));
            }
            List<ProjectYearData> yearEntityList = new ArrayList<>();
            for (ProjectYearDataDTO yearDataDTO : yearDataDTOList) {
                ProjectYearData yearEntity = new ProjectYearData();
                preInsert(yearEntity);
                yearEntity.setProjectId(id);
                yearEntity.setBatchId(batchId);
                yearEntity.setYear(yearDataDTO.getYear());
                yearEntity.setProductionRate(yearDataDTO.getProductionRate());
                yearEntity.setWaterInjection(yearDataDTO.getWaterInjection());
                yearEntity.setSteamInjection(yearDataDTO.getSteamInjection());
                yearEntity.setLiquidOutput(yearDataDTO.getLiquidOutput());
                yearEntity.setOilOutput(yearDataDTO.getOilOutput());
                yearEntity.setGasOutput(yearDataDTO.getGasOutput());
                yearEntity.setCondensateOutput(yearDataDTO.getCondensateOutput());
                yearEntity.setLiquidGasOutput(yearDataDTO.getLiquidGasOutput());
                yearEntity.setDrugCost(yearDataDTO.getDrugCost());
                yearEntity.setSumInvest(yearDataDTO.getSumInvest());
                yearEntity.setDrillExtractInvest(yearDataDTO.getDrillExtractInvest());
                yearEntity.setGroundInvest(yearDataDTO.getGroundInvest());
                yearEntity.setOtherInvest(yearDataDTO.getOtherInvest());
                yearEntity.setOutputWellOpenCount(yearDataDTO.getOutputWellOpenCount());
                yearEntity.setInjectionWellOpenCount(yearDataDTO.getInjectionWellOpenCount());
                yearEntity.setFixedPerson(yearDataDTO.getFixedPerson());
                if (MapUtils.isNotEmpty(yearDataMap)) {
                    final ProjectYearData yearData = yearDataMap.get(yearEntity.getYear());
                    if (Objects.nonNull(yearData)) {
                        yearEntity.setInvestRatio(yearData.getInvestRatio());
                        yearEntity.setOutputRatio(yearData.getOutputRatio());
                        yearEntity.setCostRatio(yearData.getCostRatio());
                    }
                }
                yearEntityList.add(yearEntity);

            }
            LambdaQueryWrapper<ProjectYearData> deleteYearDataWrapper = new LambdaQueryWrapper();
            deleteYearDataWrapper.eq(ProjectYearData::getProjectId,id);
            projectYearDataDAO.delete(deleteYearDataWrapper);

            projectYearDataDAO.insertBatch(yearEntityList);
            //projectCostDataService.deleteById(projectInfo.getId());
            final ProjectCostDataDTO projectCostDataDTO = dto.getProjectCostData();
            projectCostDataDTO.setId(id);
            projectCostDataService.update(projectCostDataDTO);
        }
        return CommonResultEnum.SUCCESS;
    }

    @Override
    public void cancelUltimate(String batchId) {
        final ProjectInfo info = new ProjectInfo();
        info.setUltimate(false);
        final QueryWrapper<ProjectInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProjectInfo::getBatchId,batchId);
        projectInfoDAO.update(info, queryWrapper);
    }


//    private List<ProjectInfoExcelDTO> filterUnqualifiedData(List<ProjectInfoExcelDTO> dataList){
//        AjaxResultVO<List<CompanyVO>> companyAjax = officeClient.queryList(new CompanyDTO());
//        List<CompanyVO> companyVOList = companyAjax.getData();
//
//        for (ProjectInfoExcelDTO projectInfoExcelDTO : dataList) {
//            //建设单位
//            String buildOffice = projectInfoExcelDTO.getBuildOffice();
//            List<CompanyVO> companyVOS = companyVOList.stream().filter(item ->
//                    item.getShortName().equals(buildOffice) || item.getName().equals(buildOffice)
//            ).collect(Collectors.toList());
//            if(companyVOS == null){
//                projectInfoExcelDTO.setBuildOffice(null);
//            }else{
//                projectInfoExcelDTO.setBuildOffice(buildOffice);
//            }
//            //评价期
//            String evaluationPeriod = projectInfoExcelDTO.getEvaluationPeriod();
//            try {
//                Double.valueOf(evaluationPeriod);
//            }catch (Exception e){
//                projectInfoExcelDTO.setEvaluationPeriod(null);
//            }
//            //建设期
//            String buildYearCount = projectInfoExcelDTO.getBuildYearCount();
//            try {
//                Double.valueOf(buildYearCount);
//            }catch (Exception e){
//                projectInfoExcelDTO.setBuildYearCount(null);
//            }
//            //产品类型
//            String productType = projectInfoExcelDTO.getProductType();
//            ProductTypeEnum productTypeEnum = ProductTypeEnum.getEnumByName(productType);
//            if(productTypeEnum == null){
//                projectInfoExcelDTO.setProductType(null);
//            }else{
//                projectInfoExcelDTO.setProductType(productTypeEnum.getId());
//            }
//            //油气品种
//            String productProperty = projectInfoExcelDTO.getProductProperty();
//            OilProductPropertyEnum productPropertyEnum = OilProductPropertyEnum.getEnumByName(productProperty);
//            if(productPropertyEnum == null){
//                projectInfoExcelDTO.setProductProperty(null);
//            }else{
//                projectInfoExcelDTO.setProductProperty(productPropertyEnum.getId());
//            }
//            //油气藏类型
//            String poolType = projectInfoExcelDTO.getPoolType();
//            OilPoolTypeEnum poolTypeEnum = OilPoolTypeEnum.getEnumByName(poolType);
//            if(poolTypeEnum == null){
//                projectInfoExcelDTO.setPoolType(null);
//            }else{
//                projectInfoExcelDTO.setPoolType(poolTypeEnum.getId());
//            }
//            //新老区
//            String areaMark = projectInfoExcelDTO.getAreaMark();
//            AreaMarkEnum areaMarkEnum = AreaMarkEnum.getEnumByName(areaMark);
//            if(areaMarkEnum == null){
//                projectInfoExcelDTO.setAreaMark(null);
//            }else{
//                projectInfoExcelDTO.setAreaMark(areaMarkEnum.getId());
//            }
//            //评价方式
//            String evaluationMethod = projectInfoExcelDTO.getEvaluationMethod();
//            EvaluationMethodEnum evaluationMethodEnum = EvaluationMethodEnum.getEnumByName(evaluationMethod);
//            if(evaluationMethodEnum == null){
//                projectInfoExcelDTO.setEvaluationMethod(null);
//            }else{
//                projectInfoExcelDTO.setEvaluationMethod(evaluationMethodEnum.getId());
//            }
//            //项目年度
//            String year = projectInfoExcelDTO.getYear();
//            try {
//                Integer.valueOf(year);
//            }catch (Exception e){
//                projectInfoExcelDTO.setYear(null);
//            }
//            //新建年产能
//            String newAnnualCapacity = projectInfoExcelDTO.getNewAnnualCapacity();
//            try {
//                Double.valueOf(newAnnualCapacity);
//            }catch (Exception e){
//                projectInfoExcelDTO.setNewAnnualCapacity(null);
//            }
//            //钻井井数
//            String newWellCount = projectInfoExcelDTO.getNewWellCount();
//            try {
//                Double.valueOf(newWellCount);
//            }catch (Exception e){
//                projectInfoExcelDTO.setNewWellCount(null);
//            }
//            //采出井开井数
//            String outputWellOpenCount = projectInfoExcelDTO.getOutputWellOpenCount();
//            try {
//                Double.valueOf(outputWellOpenCount);
//            }catch (Exception e){
//                projectInfoExcelDTO.setOutputWellOpenCount(null);
//            }
//            //注入井开井数
//            String injectWellOpenCount = projectInfoExcelDTO.getInjectWellOpenCount();
//            try {
//                Double.valueOf(injectWellOpenCount);
//            }catch (Exception e){
//                projectInfoExcelDTO.setInjectWellOpenCount(null);
//            }
//            //新增定员
//            String fixedPerson = projectInfoExcelDTO.getFixedPerson();
//            try {
//                Integer.valueOf(fixedPerson);
//            }catch (Exception e){
//                projectInfoExcelDTO.setFixedPerson(null);
//            }
//            //钻采投资
//            String drillExtractInvest = projectInfoExcelDTO.getDrillExtractInvest();
//            try {
//                Double.valueOf(drillExtractInvest);
//            }catch (Exception e){
//                projectInfoExcelDTO.setDrillExtractInvest(null);
//            }
//            //地面投资
//            String groundInvest = projectInfoExcelDTO.getGroundInvest();
//            try {
//                Double.valueOf(groundInvest);
//            }catch (Exception e){
//                projectInfoExcelDTO.setGroundInvest(null);
//            }
//            //其他投资
//            String otherInvest = projectInfoExcelDTO.getOtherInvest();
//            try {
//                Double.valueOf(otherInvest);
//            }catch (Exception e){
//                projectInfoExcelDTO.setOtherInvest(null);
//            }
//            //待利用净资产
//            String netAssetsUnUse = projectInfoExcelDTO.getNetAssetsUnUse();
//            try {
//                Double.valueOf(netAssetsUnUse);
//            }catch (Exception e){
//                projectInfoExcelDTO.setNetAssetsUnUse(null);
//            }
//        }
//
//        return dataList;
//    }

    /**
     * 主要用于将数字类型（Integer、Double）的空值转换成空字符串
     * */
    private String getNumStr(Object num){
        if(num == null){
            return "";
        }
        return String.valueOf(num);
    }

    @Override
    public String getName() {
        return "batch-project";
    }

    @Override
    public ServiceResult handleBatchDelete(String batchId) {
        return deleteByBatch(batchId);
    }
}
